package reflect;

import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.Scanner;

/**
 * java的反射机制
 * 反射是java的动态机制，允许程序在运行期间再确定如:对象实例化，方法调用，属性操作等
 * 反射可以提高代码的灵活读和可扩展性，但是会有更多的资源消耗，和较慢的运行效率
 * 因此程序不能过度的依赖反射机制
 */
public class ReflectDemo1 {
    public static void main(String[] args) throws ClassNotFoundException {
        /*
            Class类，反射对象之一
            反射操作的第一步就是获取要操作的类的类对象

            当JVM加载一个类的字节码文件时，就会实例化一个Class的实例与这个类
            绑定，因此每个被JVM加载的类都有且只有一个Class的实例。
            这个Class实例上记录了这个类的一切信息，因此通过这个类对象可以反应出
            该类的所有信息，如:类名，包信息，方法，构造器，属性等从而让我们在
            程序运行期间进行操作。

            获取一个类的类对象方式:
            1:类名.class
              例如:
              Class cls = String.class;//获取String的类对象
              Class cls = int.class;//获取int的类对象
              注意:基本类型获取类对象只有这一种方式。

            2:Class.forName("类的完全限定名")  注:完全限定名，包名.类名
              例如:
              Class cls = Class.forName("java.lang.String");
              Class cls = Class.forName("java.util.ArrayList")
              Class cls = Class.forName("int");//报错

            3:对象.getClass()
              String str = "abc";
              Class cls = str.getClass();

            4:ClassLoader.loadClass("类的完全限定名")
         */
        //获取String的类对象
//        Class cls = String.class;
//        Class cls = ArrayList.class;

        /*
            java.util.ArrayList
            java.util.HashMap
            java.io.FileInputStream
            java.lang.String
         */
//        Class cls = Class.forName("java.util.ArrayList");
        System.out.println("请输入一个类名:");
        Scanner scanner = new Scanner(System.in);
        String cName = scanner.nextLine();
        Class cls = Class.forName(cName);



        /*
            通过类对象的相关方法可以反映出其表示的类的相关信息
         */
        //获取类对象表示的类的完全限定名
        String className = cls.getName();
        System.out.println(className);
        //仅获取类名
        className = cls.getSimpleName();
        System.out.println(className);
        /*
            Class提供的方法:
            Package getPackage()
            该方法会返回当前类对象所表示的类的包信息

            Package类，包对象，它的每一个实例用于表示一个包的信息
            Package也是反射对象之一
         */
        Package pack = cls.getPackage();
        System.out.println(pack.getName());
        /*
            Method类，方法对象，它的每一个实例用于表示一个方法的信息
            Method也是反射对象之一
         */
        Method[] methods = cls.getMethods();
        System.out.println(className+"类共有:"+methods.length+"个方法");
        for (Method method:methods){
            System.out.println(method.getName());
        }
    }
}
